#include "ia.hpp"
#include "joueur.hpp"
#include <iostream>
#include <QDebug>
#include <QCoreApplication>


enum Contenu{COEURS = 0, PIQUES, CARREAUX, TREFLES, ATOUTS, 
         EXCUSES, BOUTS, VALETS, CAVALIERS, DAMES, ROIS};

std::vector<int> informations_calculees(const std::vector<Carte> & cartes)
{
  qDebug()<<"entree informations_calculees\n";
  std::vector<int> resultat(11,0);
  unsigned int place = 0;
  for(unsigned int i = 0 ; i < cartes.size() ; i++)
    {
      switch(cartes[i].couleur())
	{
	case Carte::COEUR: place = COEURS; break;
	case Carte::PIQUE: place = PIQUES; break;
	case Carte::CARREAU: place = CARREAUX; break;
	case Carte::TREFLE: place = TREFLES; break;
	default:
	  if(cartes[i] == EXCUSE)
	    {
	      place = EXCUSES;
	    }
	  else
	    {
	      place = ATOUTS;
	    }
	}
      resultat[place]++;
      if(cartes[i].bout())resultat[BOUTS]++;
      if(!(cartes[i].atout()) && cartes[i] != EXCUSE)
	switch(cartes[i].valeur())
	  {
	  case Carte::ROI: resultat[ROIS]++; break;
	  case Carte::DAME: resultat[DAMES]++; break;
	  case Carte::CAVALIER: resultat[CAVALIERS]++; break;
	  case Carte::VALET: resultat[VALETS]++; break;
	  default: break;
	  }
    }
  qDebug()<<"sortie informations_calculees\n";
  return resultat;
}

int compteur(const std::vector<Carte> & main, const std::vector<int> & pv)
{
  qDebug()<<"entree compteur\n";
  //Test
  int compteur = 0;
  for(unsigned int i = 0 ; i < main.size() ; i++)
    {
      //Ajout des pseudovaleurs de la main au compteur
      compteur += pv[main[i].numero()];

    }
  //Statistiques sur ma main
  std::vector<int> info = informations_calculees(main);
  //Bonus en fonction du nombre d'atouts
  if(info[ATOUTS] >= 5 && info[ATOUTS] < 8) compteur += 25;
  if(info[ATOUTS] >= 8 && info[ATOUTS] < 10) compteur += 35;
  if(info[ATOUTS] >= 10 && info[ATOUTS] < 12) compteur += 50;
  if(info[ATOUTS] >= 12) compteur += 1000;  

  std::vector<int> nombre_longues(9);
  //Nombre de longues à n cartes
  for(int n = 4 ; n <= 13 ; n++)
    {
      nombre_longues[n - 4] = 0;
      for(unsigned int i = 0 ; i < 4 ; i++)
	{
	  if(info[i] >= n)nombre_longues[n - 4]++;
	}
    }
  //Bonus-malus en fonction des longues.
  if(nombre_longues[0] >= 2) compteur -= 20; //2 longues de plus de 4
					     //cartes 
  if(info[ATOUTS]>=6) // Bonus longue que si on a suffisamment d'atouts
  {
    compteur += 10 * nombre_longues[1];
    compteur += 13 * nombre_longues[2];
    compteur += 10 * nombre_longues[3];
  }

  compteur -= 15 * nombre_longues[4];// Malus (longue encombrante)
  compteur -= 30 * nombre_longues[6];
  compteur -= 1000 * nombre_longues[8];

  switch(info[BOUTS]) //Bonus en fonction du nombre de bouts 
    {
    case 0 : compteur -=20; break;
    case 1 : compteur += 5; break;
    case 2 : compteur += 15; break;
    case 3 : compteur += 20;
    default : break;
    }

  // Bonus coupe direct et singlette
  for(unsigned int i = 0 ; i < 4 ; i++)
    {
      if(info[i] == 0)compteur+=10;
      if(info[i] == 1)compteur+=8;
    }
  qDebug()<<"Sortie compteur\n";
  return compteur;
}

std::vector<int> pseudo_valeurs()
{
  std::vector<int> p;
  p.resize(78);
  Carte c(1);
  for(unsigned int i = 0 ; i < 78 ; i++)
  {
      c = i;
      if(!c.atout())
      {
	  if(c.valeur() < Carte::VALET)
	    {
	      p[i] = 0;
	    }
	  else
	    {
	      switch(c.valeur())
          {
          case Carte::VALET: p[i] = 2; break;
          case Carte::CAVALIER: p[i] = 3; break;
          case Carte::DAME: p[i] = 4; break;
          case Carte::ROI: p[i] = 8; break;
          default: break;
          }
	    }
      }
      else
      {
	  if(c.valeur () >= 2 && c.valeur() <= 14)
	    {
	      p[i] = 2;
	    }
	  else if(c.valeur() >= 15 && c.valeur() <= 20)
	    {
	      p[i] = 3;
	    }
	  else if(c == PETIT || c == EXCUSE)
	    {
          p[i] = 9;
	    }
      else //21
	    {
          p[i] = 10;
	    }
      }
    }
  return p;
}

Ia::Ia(const QString & nom, const QVector<QString> & equipe, QObject * parent):
  QObject(parent),
  nom_souhaite(nom),
  equipe_souhaitee(equipe),
  m_deconnexion_voulue(false),
  jeu(this),
  pseudo_valeurs_cartes(pseudo_valeurs())
{
    qDebug()<<"entree constructeur\n";

    for(unsigned int i=0;i<5;i++)
    {
        Joueur j(i);
        joueurs.push_back(j);
    }
/*#ifdef TESTER_REPARTITION
  std::vector<Carte> truc;
  unsigned int x;
  for(unsigned int i = 0 ; i < 15 ; i++)
    {
      x = rand () % 78;
      std::cout<<Carte(x)<<std::endl;
      truc.push_back(Carte(x));
    }
  //std::cout<<"Résultat : "<<informations_calculees(truc)<<std::endl;
#endif

#ifdef TESTER_PSEUDOVALEURS
  std::cout<<"Pseudo-valeurs : "<<std::endl;
  for(unsigned int i = 0; i < pseudo_valeurs_cartes.size() ; i++)
    {
      std::cout<<"Pseudo-valeur de "<<Carte(i)<<" : "
	       <<pseudo_valeurs_cartes[i]<<"."<<std::endl;
    }
#endif

#ifdef TESTER_COMPTEUR
  std::cout<<"Test du compteur : 20 distributions."<<std::endl;
  for(unsigned int d = 0 ; d < 20 ; d++)
    {
      std::cout<<"Distribution "<<d<<" : "<<std::endl;
      std::vector<Carte> main;
      for(unsigned int c = 0 ; c < 15 ; c++)
	{
	  unsigned int j = 0;
	  Carte carte(rand() % 78);
	  while(j < main.size())
	    {
	      carte = (rand() % 78);
	      for(j = 0 ; j < main.size() && main[j] != carte ; j++);
	    }
	  main.push_back(carte);
	}
      for(unsigned int i = 0 ; i < 78 ; i++)
	{
	  unsigned int j = 0;
	  for(j = 0 ; j < main.size() && main[j] != i ; j++);
	  if(j < main.size())
	    {
	      std::cout<<Carte(i)<<std::endl;
	    }
	}
      std::vector<int> pv = pseudo_valeurs();
      std::cout<<"Compteur : "<<compteur(main, pv)<<std::endl;
    }
#endif
*/
#define c(signal) QObject::connect(&jeu, SIGNAL(signal),	\
				   this, SLOT(signal))
  c(deconnecte()); //Quitte le programme.
  c(doit_identifier()); //Donne son nom.
  c(identification_refusee(std::string)); //Quitte
  c(adversaires(std::vector<std::string>)); //Vérifie si ce sont bien
  //ceux qu'on veut, se reconnecte dans le cas contraire
  c(doit_priser(Option<Enchere>));
  c(jeu_est(std::vector<Carte>)); //Tient mon jeu à jour.
  c(doit_jouer()); //Joue la carte
  c(doit_appeler(std::vector<Carte>));
  c(contrat_final(Enchere));
  c(tapis_change(Tapis));
  c(doit_ecarter(std::vector<Carte>, std::vector<Carte>));
  c(requete_refusee(Carte ));
  c(numero_change(unsigned int));
  c(partie_terminee(std::vector<int>));

#define r(signal) QObject::connect(this, SIGNAL(signal),	\
				   &jeu, SLOT(signal));
  r(formuler_identification(std::string));
  r(formuler_prise(Enchere::Prise)); //Nécessaire
  r(formuler_requete(Carte));
  r(formuler_appel(Carte));
  r(formuler_ecart(std::vector<Carte>));
  r(deconnecter()); //Nécessaire pour refuser une invitation.
  r(reconnecter());
  qDebug()<<"Connexions slots\n";

  std::cout<<"Initialisation de l'IA reussie";

  qDebug()<<"Sortie constructeur\n";
}

void Ia::connecter(QString hote, quint16 port)
{
  jeu.connecter(hote, port);
  std::cout<<"Connection en cours\n";
}

void Ia::deconnecte()
{
  //Si j'ai souhaité me déconnecter, je me reconnecte :
  if(m_deconnexion_voulue)
    {
      m_deconnexion_voulue = false;
      emit reconnecter();
    }
  //Sinon, j'ai fini mon job (la partie a été fermée)
  else
    {
      emit doit_quitter();
    }
}

void Ia::doit_identifier()
{
  //Conversion en std::string
  std::string nom(nom_souhaite.toUtf8().data());
  std::cout<<"Je m'identifie\n";
  emit formuler_identification(nom);
}

void Ia::identification_refusee(std::string)
{
  //ERREUR : je n'ai pas réussi à prendre ce nom !
  emit doit_quitter();
}

void Ia::adversaires(std::vector<std::string> adversaires)
{
  bool trouve = false; //A-t-on trouvé cet adversaire dans l'équipe
		       //souhaitée ?  
  bool ok = true; //A-t-on trouvé tous ceux qu'on voulait ?
  //Parcourons la liste d'adversaires...
  for(unsigned int i = 0 ; i < adversaires.size() && ok ; i++)
    {
      trouve = false;
      //Parcourons l'équipe souhaitée...
      for(int j = 0 ; j < equipe_souhaitee.size() && (!trouve) ; j++)
	{
	  if(equipe_souhaitee[j] == QString::fromUtf8(adversaires[i].c_str()))
	    {
	      //Trouvé !
	      trouve = true;
	    }
	}
      ok = (ok && trouve) ;
    }
  if(!ok)
    {
      //Je me reconnecte
      emit deconnecter();
    }
}

void Ia::doit_priser(Option<Enchere> min)
{
    qDebug()<<"entree doit_priser\n";
    const PartieClient & partie = jeu.partie();
    const Main & ma_main = partie.mon_jeu();
 //   emit formuler_prise(super_fonction(ma_main, cartes_jouees));

    const std::vector<Carte> & mon_jeu = ma_main.cartes();
    const std::vector<int> pv = pseudo_valeurs();

  int c=compteur(mon_jeu, pv);

  int min_a_faire=0;
  if (!min.aucun())
  {
      Enchere e=min.get();
      min_a_faire= (int) e.prise();
  }


  if(c<=30)
  {
      emit formuler_prise(Enchere::PASSE);
  }
  else if (c<=50 && min_a_faire < 1)
  {
      emit formuler_prise(Enchere::PRISE);
  }
  else if (c<=80 && min_a_faire < 2)
  {
      emit formuler_prise(Enchere::GARDE);
  }
  else if (c<=110 && min_a_faire < 3)
  {
      emit formuler_prise(Enchere::GARDE_SANS);
  }
  else if (min_a_faire < 4)
  {
      emit formuler_prise(Enchere::GARDE_CONTRE);
  }
  else
  {
      emit formuler_prise(Enchere::PASSE);
  }

  qDebug()<<"sortie doit_priser\n";
}

void Ia::jeu_est(std::vector<Carte>)
{
}

void Ia::doit_jouer()
{

  qDebug()<<"entree doit_jouer\n";
  const PartieClient & partie = jeu.partie();
  const Main & ma_main = partie.mon_jeu();
  std::vector<Carte> mon_jeu = ma_main.cartes();


  std::vector<Carte> mon_jeu_jouable;
  std::vector<int> correspondance(78);

  const Tapis tapis=partie.tapis();
  Carte c_entame;
  tapis.entame(c_entame);
  Carte::Couleur couleur_entame=c_entame.couleur();



  std::vector<Carte> cartes;
  std::vector<unsigned int> poseurs;
  tapis.contenu(cartes,poseurs);
  unsigned int n=poseurs.size();

  bool coupe=false;
  bool je_coupe=false;
  unsigned int atout_min=0; //Valeur de l'atout minimum sur lequel il faut enchérire

  // Tête max déjà jouée
  Carte::Valeur tete_max=Carte::AS;
  if(couleur_entame!=Carte::ATOUT)
  {
      for(unsigned int i=0;i<cartes_jouees.size();i++)
      {
          if(cartes_jouees[i].couleur()==couleur_entame && cartes_jouees[i].valeur()>tete_max)
              tete_max=cartes_jouees[i].valeur();
      }
  }


  bool maitre_couleur = false;

  /* Permet de déterminer s'il y a un atout sur le tapis et la valeur minimum à utiliser pour remporter le pli
   * ainsi que la tête a battre de la couleur */
  for(unsigned int i=0;i<cartes.size();i++)
  {
      if(cartes[i].couleur()==Carte::ATOUT && cartes[i]!=EXCUSE)
      {
          coupe=true;
          if(cartes[i].valeur()>atout_min)
              atout_min=cartes[i].valeur();
      }
      else if(c_entame.couleur()!=Carte::ATOUT)
      {
          if(cartes[i].valeur()==tete_max) // la tête maitre a été posée : aucun autre joueur ne pourra être maitre à la couleur
             maitre_couleur=true;
      }
  }

  Carte::Valeur v=Carte::Valeur(22);
  Carte c;





  unsigned int tour=15-mon_jeu.size()+1;

  //Détermination du jeu jouable
  std::vector<int> infos = informations_calculees(mon_jeu);
  bool equipe_remporte_pli=false;

    qDebug()<<"infos sur le tapis faites\n";

    bool atout_superieur_a_atout_min=false;
  for(unsigned int i = 0;i<mon_jeu.size();i++)
  {
      if (mon_jeu[i].numero()==EXCUSE)
          mon_jeu_jouable.push_back(mon_jeu[i]);
      else if(mon_jeu[i].couleur()==c_entame.couleur() && mon_jeu[i].couleur()!=Carte::ATOUT) // Même couleur hors atout
          mon_jeu_jouable.push_back(mon_jeu[i]);
      else if(mon_jeu[i].couleur()==c_entame.couleur() && mon_jeu[i].couleur()==Carte::ATOUT && mon_jeu[i].valeur()>atout_min) // Entame à l'atout, on a pas le droit de jouer un atout plus faible
      {
          mon_jeu_jouable.push_back(mon_jeu[i]);
          atout_superieur_a_atout_min=true;
          je_coupe=true;
      }
      else if(c_entame.couleur()!=Carte::ATOUT && mon_jeu[i].couleur()==Carte::ATOUT && infos[c_entame.couleur()]==0 && mon_jeu[i].valeur()>atout_min) // On coupe
      {
          mon_jeu_jouable.push_back(mon_jeu[i]);
          je_coupe=true;
          atout_superieur_a_atout_min=true;
      }
      else if (c_entame.couleur()!=Carte::ATOUT && mon_jeu[i].couleur()!=Carte::ATOUT && infos[c_entame.couleur()]==0 && infos[ATOUTS]==0) // On doit couper mais on a plus d'atout
          mon_jeu_jouable.push_back(mon_jeu[i]);
      else if(c_entame.couleur()==Carte::ATOUT && mon_jeu[i].couleur()!=Carte::ATOUT && infos[Carte::ATOUT]==0) //entame à l'atout mais j'ai plus d'atout
          mon_jeu_jouable.push_back(mon_jeu[i]);

  }

  if(!atout_superieur_a_atout_min)
  {
      for(unsigned int i=0;i<mon_jeu.size();i++)
      {
          if(mon_jeu[i].couleur()==Carte::ATOUT && mon_jeu[i].numero()!=EXCUSE)
          {
             mon_jeu_jouable.push_back(mon_jeu[i]);
          }

      }
  }

//Correspondance entre id des cartes et place dans mon_jeu_jouable
  for (unsigned int i=0;i<mon_jeu_jouable.size();i++)
  {
      correspondance[mon_jeu_jouable[i].numero()]=i; //correspondance[id de la carte]=Place dans le vecteur mon_jeu_jouable
  }


  qDebug()<<"détermination jeu jouable\n";
  qDebug()<<"Mon jeu jouable est : ";
  for(unsigned int i=0;i<mon_jeu_jouable.size();i++)
  {
      qDebug()<<mon_jeu_jouable[i].nom().c_str();
  }


  //Détermination du maitre supposé
 Joueur maitreSuppose;
 unsigned int maitre;
 bool maitre_existe = tapis.maitre(maitre); // maitre jusque là

 qDebug()<<"La valeur de maitre est " << maitre << "\n";

 if(maitre_existe)
 {
    maitreSuppose = joueurs[maitre];
    equipe_remporte_pli = joueurs[maitre].allie();
 }
 else
 {
     equipe_remporte_pli = false;
 }

 std::vector<int> info = informations_calculees(mon_jeu_jouable);


 if (ma_main.possede(Carte(EXCUSE)) && tour==14) // Avant-dernier tour, je sauve l'excuse
 {
     emit formuler_requete(mon_jeu[correspondance[EXCUSE]]);
 }
 else
 {

  if(tapis.entame(c_entame)) // Il y a une carte d'entame
  {
      if(c_entame!=EXCUSE) // La carte d'entame n'est pas l'excuse
      {

        for(unsigned int i=0;i<5-n+1;i++) // Je teste pour chaque joueur suivant s'il peut remporter le pli compte tenu des hypothèses
        {
            if(couleur_entame==Carte::ATOUT) //Ce n'est pas l'excuse mais un vrai atout. Tout le monde met son atout le plus fort
            {
                if(joueurs[(mon_id+i)%5].possede(Carte::ATOUT) && joueurs[(mon_id+i)%5].atout_max()>=atout_min) //Le joueur met potentiellement son meilleur atout possible
                {
                    atout_min=joueurs[(mon_id+i)%5].atout_max();
                    equipe_remporte_pli=joueurs[(mon_id+i)%5].allie();
                }

            }
            else // La carte d'entame est une couleur de base
            {
                if (joueurs[(mon_id+i)%5].possede(couleur_entame)) //il joue la meilleur carte de la couleur
                {
                    if(!coupe) //Personne n'a coupé. Peut remporter le pli si la meilleur tête de la couleur n'a pas été joué
                    {

                        if(!maitre_couleur)
                            equipe_remporte_pli=joueurs[(mon_id+i)%5].allie();
                    }

                }
                else if (joueurs[(mon_id+i)%5].possede(Carte::ATOUT)) //il coupe avec son meilleur atout
                {
                    coupe=true;
                    if(joueurs[(mon_id+i)%5].atout_max()>=atout_min)
                    {
                        atout_min=joueurs[(mon_id+i)%5].atout_max();
                        equipe_remporte_pli=joueurs[(mon_id+i)%5].allie();
                    }

                }
                //sinon il ne remportera pas le pli : pas de changement

            }


        }





      }
      else
          equipe_remporte_pli=false;


  }
  else
      equipe_remporte_pli=false;
  qDebug()<<"Détermination du gagnant courant \n";
  if(equipe_remporte_pli)
  {
      if(je_coupe) // Je met l'atout avec la valeur la plus faible sauf le petit
      {
          v=Carte::Valeur(22);

          for(unsigned int i=0;i<mon_jeu_jouable.size();i++)
          {
              if (mon_jeu_jouable[i].valeur()<=v && mon_jeu_jouable[i]!=PETIT && mon_jeu_jouable[i]!=EXCUSE )
              {
                c=mon_jeu_jouable[i];
                v=c.valeur();
              }

          }
          if(v!=22) // On a un atout autre que le petit
              emit formuler_requete(c);
          else //On doit jouer le petit
              emit formuler_requete(mon_jeu[correspondance[PETIT]]);
      }
      else // Je met la carte la plus forte (en valeur)
      {
          v=Carte::Valeur(0);
          for(unsigned int i=0;i<mon_jeu_jouable.size();i++)
          {
              if (mon_jeu_jouable[i].valeur()>=v && mon_jeu_jouable[i]!=PETIT && mon_jeu_jouable[i]!=EXCUSE )
              {
                c=mon_jeu_jouable[i];
                v=c.valeur();
              }

          }
      emit formuler_requete(c);
      }
  }
  else // Mon équipe perd le pli. Je joue  une carte faible : la plus faible valeur excepté petit ou excuse
  {
    bool trouve=false;

      for(unsigned int i=0;i<mon_jeu_jouable.size();i++)
      {
          if (mon_jeu_jouable[i].valeur()<=v && mon_jeu_jouable[i]!=PETIT && mon_jeu_jouable[i]!=EXCUSE )
          {
            c=mon_jeu_jouable[i];
            v=c.valeur();
            trouve=true;
          }

      }

      if(trouve)
           emit formuler_requete(c);
      //Sinon j'essaie de jouer l'excuse

      else if(ma_main.possede(Carte((unsigned int)EXCUSE)))
          emit formuler_requete(Carte((unsigned int)EXCUSE));
      else if(ma_main.possede(Carte((unsigned int)PETIT)))
          emit formuler_requete(Carte((unsigned int)PETIT));

      //Sinon je suis obligé de jouer le petit



   }


}

  qDebug()<<"sortie de doit_jouer\n";

}

 void Ia::tapis_change(Tapis tapis)
 {
     qDebug()<<"entree tapis_change\n";
     std::vector<Carte> cartes;
     std::vector<unsigned int> joueurs_num;


     tapis.contenu(cartes,joueurs_num);
    if(cartes.size()!=0)
    {
     qDebug()<<"Contenu du tapis : ";
     for(unsigned int i=0;i<cartes.size();i++)
     {
     qDebug()<<"Joueur : "<<joueurs_num[i]<<"Carte : "<<cartes[i].numero();
     }

     Carte c_entame;
     tapis.entame(c_entame);

     qDebug()<<"Carte entame : "<<c_entame.numero();
     Carte::Couleur couleur_e=c_entame.couleur();
     qDebug()<<"Couleur entame : "<<(int)couleur_e;

     unsigned int n=joueurs_num.size();
     qDebug()<<"n = "<<n;
     Carte c_jouee = cartes[n-1];
     qDebug()<<"carte jouée : "<<c_jouee.numero();
     Carte::Couleur couleur_j=c_jouee.couleur();
     qDebug()<<"Couleur jouee : "<<(int)couleur_j;

     Carte c_appelee =*(contratFinal.carte_appelee());
     qDebug()<<"Carte appelé : "<<c_appelee.numero();

     bool coupe; //si je doit jouer un atout

     unsigned int id = joueurs_num[n-1];

     qDebug()<<"L'id vaut "<<id;
     cartes_jouees.push_back(c_jouee);
     qDebug()<<"Initialisation faites";
     //Modification des infos sur le joueur qui vient de jouer

     if(couleur_e != Carte::ATOUT)
     {
         qDebug()<<"Carte entame différente de atout";
         if(c_jouee.couleur() != c_entame.couleur() && c_entame !=EXCUSE )
         {
             qDebug()<<"Carte jouée d'une autre couleur et pas l'excuse";
             coupe=true;
             joueurs[id].set_possede(couleur_e,false); // le joueur ne possede pas la couleur de l'entame
             qDebug()<<"Le joueur ne possède plus cette couleur";
             if(couleur_j != Carte::ATOUT) //le joueur possède plus d'atout non plus
             {
                 qDebug()<<"Carte jouee differente de atout : le joueur ne possède plus d'atout non plus";
                 joueurs[id].set_possede(Carte::ATOUT,false);
             }
         }
         else if(c_jouee.couleur()==c_entame.couleur())
         {
             qDebug()<<"Même couleur carte jouee et entame : le joueur possede encore cette couleur a priori";
             joueurs[id].set_possede(couleur_e,true);
         }
     }
     else if(c_entame !=EXCUSE) // l'entame est un vrai atout
     {
         qDebug()<<"Carte entame atout autre que l'excuse";
         coupe=true;
         if(couleur_j != Carte::ATOUT) //je ne possède plus d'atout non plus
         {
             qDebug()<<"Je joue autre chose qu'un atout : je n'en ai plus";
             joueurs[id].set_possede(Carte::ATOUT,false);
         }
     }
     qDebug()<<"Modification coupes sur le joueur qui vient de jouer";

     //Modification de atout max
     if(coupe) //le joueur a du couper
     {
         qDebug()<<"Le joueur coupe";
         if(!joueurs[id].possede(Carte::ATOUT) )
         {
             qDebug()<<"Le joueur ne possede plus d'atout";
             joueurs[id].set_atout_max(0);
             qDebug()<<"Mise atout_max à 0 pour ce joueur";

         }
         else // Verification si on a jouer un atout plus faible
         {
             qDebug()<<"Determination si on a joué un atout plus faible";
             unsigned int max=0;
             for(unsigned int i=0;i<n;i++)
             {
                 qDebug()<<"Détermination atout max joué";
                 if(cartes[i].couleur()==Carte::ATOUT&&cartes[i].valeur()>max)
                     max=cartes[i].valeur();
             }
             if(c_jouee.valeur()<max)
                 qDebug()<<"Modification atout max du joueur";
                 joueurs[id].set_atout_max(max-1);
         }

     }
      qDebug()<<"Modifications de l'atout max du joueur qui vient de jouer\n";

     //Mise à jour des équipes
     if(c_jouee==c_appelee)
     {
         if(equipe==ATTAQUANT) //Je suis attaquant
         {
             joueurs[id].set_allie(true);
             for(unsigned int j=0;j<5;j++)
             {
                 if(joueurs[j].preneur()==false && j!=id) //j est défenseur
                     joueurs[j].set_allie(false);
             }
         }
         else // Je suis défenseur
             joueurs[id].set_allie(false);
             for(unsigned int j=0;j<5;j++)
             {
                if(joueurs[j].preneur()==false && j!=id) //j est défenseur
                    joueurs[j].set_allie(true);
             }
     }

      qDebug()<<"Modification des équipes\n";
    }
      qDebug()<<"sortie tapis_change\n";


 }

void Ia::doit_appeler(std::vector<Carte>)
{

    qDebug()<<"entree doi_appeler\n";
    const PartieClient & partie = jeu.partie();
    const Main & ma_main = partie.mon_jeu();
    const std::vector<Carte> & mon_jeu = ma_main.cartes();
    std::vector<int> infos=informations_calculees(mon_jeu);
    //COEURS = 0, PIQUES, CARREAUX, TREFLES, ATOUTS, EXCUSES, BOUTS, ROIS, DAMES, CAVALIERS, VALETS
    std::vector<int> couleurs(4);
    Carte carte_appele;

    /* Classement des couleurs par ordre décroissant
     *
     *
     * */

    for (unsigned int i=0;i<couleurs.size();i++)
    {
        int indice=0;
        int max=0;
        for (unsigned int j=0;j<couleurs.size();j++)
        {
            if (max<infos[j])
            {
                max=infos[j];
                indice=j;
            }
        }
        couleurs[i]=indice;
        infos[indice]=0;

    }


    for (int tete = Carte::ROI;tete>=Carte::VALET;tete--)
    {
        if(infos[tete-3]!=4) // L'IA n'a pas tous les rois ou toutes les dames, ...
        {
            for(unsigned int i=0;i<4;i++)
            {
                int couleur=couleurs[(i+1)%4]; //2eme couleur la plus présente, puis 3eme, puis 4eme, puis 1ere
                unsigned int id=couleur*14+tete;
                const Carte car(id);
                if(!ma_main.possede(car))
                {
                    //on appelle cette carte
                    jeu.formuler_appel(car);

                    qDebug()<<"Détermination de l'appel\n";
                    break;

                }


            }
        break; //On a appelé vu qu'on avait pas les 4 têtes concernées
        }
    }



}

void Ia::doit_ecarter(std::vector<Carte> possibles, std::vector<Carte> atouts)
{
    qDebug()<<"entree doit_ecarter\n";
    const PartieClient & partie = jeu.partie();
    const Main & ma_main = partie.mon_jeu();
    const std::vector<Carte> & mon_jeu_const = ma_main.cartes();
    std::vector<Carte> mon_jeu = mon_jeu_const;
    std::vector<int> infos = informations_calculees(mon_jeu);

    Carte carte_appele=*(contratFinal.carte_appelee());


    std::vector<Carte> cartes_ecartees;
    //COEUR, PIQUE, CARREAU, TREFLE, ATOUT

    if(possibles.size()>=3)
    {


    //ecarter les dames sèches, cavaliers secs, valet sec, singlette
    for(unsigned int i=0; i<4;i++)
    {
        Carte::Couleur c=(Carte::Couleur)i;
        unsigned int id=i*14+14;
        Carte roi(id);

        if(infos[i]==1 && cartes_ecartees.size()<3 && carte_appele.couleur()!=c && !ma_main.possede(roi)) // On a qu'une seule carte de la couleur
        {
            for(unsigned int i=0; i<mon_jeu.size();i++)
            {
                if(mon_jeu[i].couleur()==c)
                {
                    cartes_ecartees.push_back(mon_jeu[i]);
                    mon_jeu.erase(mon_jeu.begin()+i);
                }
            }
        }
    }
    qDebug()<<"Ecarter dames seches etc singlettes"<<"Cartes ecartees : ";
    for(unsigned int i=0;i<cartes_ecartees.size();i++)
    {
        qDebug()<<cartes_ecartees[i].numero()<<" ";
    }

    if(cartes_ecartees.size()!=3)
    {

        //Faire une coupe pour une couleur dont on a pas le roi et qu'on a pas appelé
        for(unsigned int i=0; i<4;i++)
        {
            Carte::Couleur c=(Carte::Couleur)i;
            unsigned int id=i*14+14;
            Carte roi(id);

            if(((infos[i]==1 && cartes_ecartees.size()<3)
            ||(infos[i]==2 && cartes_ecartees.size()<2)
            ||(infos[i]==3 && cartes_ecartees.size()<1))
                    && carte_appele.couleur()!=c && !ma_main.possede(roi)
                     ) // On a qu'une seule carte de la couleur
            {
                for(unsigned int i=0; i<mon_jeu.size();i++)
                {
                    if(mon_jeu[i].couleur()==c)
                    {
                        cartes_ecartees.push_back(mon_jeu[i]);
                        mon_jeu.erase(mon_jeu.begin()+i);
                    }
                }
            }
        }
    qDebug()<<"faire coupes"<<"Cartes ecartees : ";
    for(unsigned int i=0;i<cartes_ecartees.size();i++)
    {
        qDebug()<<cartes_ecartees[i].numero()<<" ";
    }
    }

    if(cartes_ecartees.size()!=3)
    {
        //Faire une singlette pour une couleur dont on a pas le roi et qu'on a pas appelé
        for(unsigned int i=0; i<4;i++)
        {
            Carte::Couleur c=(Carte::Couleur)i;
            unsigned int id=i*14+14;
            Carte roi(id);

            if(((infos[i]==2 && cartes_ecartees.size()<3)
            ||(infos[i]==3 && cartes_ecartees.size()<2)
            ||(infos[i]==4 && cartes_ecartees.size()<1))
                && carte_appele.couleur()!=c && !ma_main.possede(roi)
                 ) // On a qu'une seule carte de la couleur
            {
                for(unsigned int i=0; i<mon_jeu.size();i++)
                {
                    if(mon_jeu[i].couleur()==c)
                    {
                        cartes_ecartees.push_back(mon_jeu[i]);
                        mon_jeu.erase(mon_jeu.begin()+i);
                    }
                }
            }
        }
    qDebug()<<"faire singlette pour recuperer le roi"<<"Cartes ecartees : ";
    for(unsigned int i=0;i<cartes_ecartees.size();i++)
    {
        qDebug()<<cartes_ecartees[i].numero()<<" ";
    }
    }

    if(cartes_ecartees.size()!=3)
    {

        //Singlette roi (idée : couper la dame)

        for(unsigned int i=0; i<4;i++)
        {
            Carte::Couleur c=(Carte::Couleur)i;
            unsigned int id=i*14+14;
            Carte roi(id);

            if(((infos[i]==2 && cartes_ecartees.size()<3)
            ||(infos[i]==3 && cartes_ecartees.size()<2)
            ||(infos[i]==4 && cartes_ecartees.size()<1))
                && carte_appele.couleur()!=c && ma_main.possede(roi)
                 ) // On a qu'une seule carte de la couleur
            {
                for(unsigned int i=0; i<mon_jeu.size();i++)
                {
                    if(mon_jeu[i].couleur()==c && mon_jeu[i]!=roi)
                    {
                        cartes_ecartees.push_back(mon_jeu[i]);
                        mon_jeu.erase(mon_jeu.begin()+i);
                    }
                }
            }
        }
    qDebug()<<"faire singlette roi"<<"Cartes ecartees : ";
    for(unsigned int i=0;i<cartes_ecartees.size();i++)
    {
        qDebug()<<cartes_ecartees[i].numero()<<" ";
    }
    }

    if(cartes_ecartees.size()!=3)
    {

        //Sauver les points
        for(unsigned int i=0; i<mon_jeu.size();i++)
        {
            if(mon_jeu[i].couleur()!=Carte::ATOUT && mon_jeu[i].valeur()>=Carte::VALET
                && mon_jeu[i].valeur()!=Carte::ROI && cartes_ecartees.size()<3)
            {
                cartes_ecartees.push_back(mon_jeu[i]);
                mon_jeu.erase(mon_jeu.begin()+i);
            }
        }
        qDebug()<<"sauver points"<<"Cartes ecartees : ";
        for(unsigned int i=0;i<cartes_ecartees.size();i++)
        {
            qDebug()<<cartes_ecartees[i].numero()<<" ";
        }
    }

    if(cartes_ecartees.size()!=3)
    {

        //Mettre toutes les autres cartes hors atout
        for(unsigned int i=0; i<mon_jeu.size();i++)
        {
            if(mon_jeu[i].couleur()!=Carte::ATOUT && cartes_ecartees.size()<3 && mon_jeu[i].valeur()!=Carte::ROI)
            {
                 cartes_ecartees.push_back(mon_jeu[i]);
                 mon_jeu.erase(mon_jeu.begin()+i);
            }
        }
    qDebug()<<"autres cartes non atout"<<"Cartes ecartees : ";
    for(unsigned int i=0;i<cartes_ecartees.size();i++)
    {
        qDebug()<<cartes_ecartees[i].numero()<<" ";
    }
    }
    }
    else // 3 cartes ou moins hors atout
    {
        for(unsigned int i=0;i<possibles.size();i++)//On remplit avec les cartes possibles
            cartes_ecartees.push_back(possibles[i]);

        if(cartes_ecartees.size()!=3)//On doit mettre des atouts
            {
                unsigned int i=0;
                while(cartes_ecartees.size()!=3)
                {
                    cartes_ecartees.push_back(atouts[i]);
                }
            }
    }
    qDebug()<<"mettre atouts";


    emit formuler_ecart(cartes_ecartees);
    qDebug()<<"sortie doit_ecarter\n";
}

void Ia::contrat_final(Enchere e)
{

    qDebug()<<"entrée contrat_final\n";
    unsigned int i=e.joueur();
    joueurs[i].set_preneur(true);
    contratFinal=e;
    Carte c_appelee=*(e.carte_appelee());

    qDebug()<<"Initialisation contrat_final";

    for(unsigned int j=0;j<5;j++)
    {
        joueurs[j].set_possede((Carte::Couleur)j,false);
    }

    qDebug()<<"Mise à jour coupes";

    const PartieClient & partie = jeu.partie();
    const Main & ma_main = partie.mon_jeu();
    //const std::vector<Carte> & mon_jeu = ma_main.cartes();

    if(i==mon_id || ma_main.possede(c_appelee)) // J'ai appelé ou j'ai le roi
        equipe=ATTAQUANT;
    else
        equipe=DEFENSEUR;

    qDebug()<<"Détermination équpes attaquant/defenseur";

    if(ma_main.possede(c_appelee))
    {
        qDebug()<<"je possede la carte appelee et i="<<i<<" et mon id vaut "<<mon_id;
        joueurs[i].set_allie(true);
        joueurs[mon_id].set_allie(true);
        for(unsigned j=0;j<5;j++)
        {
            if(j!=i && j!=mon_id)
                joueurs[j].set_allie(false);
        }

    }
    qDebug()<<"Détermination alliés/ennemis";
    qDebug()<<"sortie contrat_final\n";

}

void Ia::requete_refusee(Carte c)
{
   qApp->quit();
}

void Ia::numero_change(unsigned int num)
{
    mon_id = num;
}

void Ia::partie_terminee(std::vector<int> scores)
{
    cartes_jouees.clear();
    joueurs.clear();
    for(unsigned int i=0;i<5;i++)
    {
        Joueur j(i);
        joueurs.push_back(j);
    }

}
